/**
 * 	Copyright 2009 RJ Regenold 
 *	
 *	Licensed under the Apache License, Version 2.0 (the "License"); 
 *	you may not use this file except in compliance with the License. 
 *	You may obtain a copy of the License at 
 *	
 *		http://www.apache.org/licenses/LICENSE-2.0 
 *		
 *	Unless required by applicable law or agreed to in writing, software 
 *	distributed under the License is distributed on an "AS IS" BASIS, 
 *	WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
 *	See the License for the specific language governing permissions and 
 *	limitations under the License. 
 */

package com.binarylion.puremvc.core {
	
	import com.binarylion.puremvc.interfaces.IFountController;
	import com.binarylion.puremvc.registration.RegistrationClient;
	import com.binarylion.puremvc.registration.RegistrationRequestContext;
	
	import mx.utils.StringUtil;
	
	import org.as3commons.lang.Assert;
	import org.puremvc.as3.core.Controller;
	import org.puremvc.as3.patterns.observer.Observer;
	import org.springextensions.actionscript.context.IConfigurableApplicationContext;
	import org.springextensions.actionscript.context.support.XMLApplicationContext;
	
	public class FountController extends Controller implements IFountController {
		
		/**
		 * Gets an instance of the controller.
		 * @return the controller
		 */
		public static function getInstance():FountController {
			if(!instance) {
				instance = new FountController();
			}
			return instance as FountController;
		}
		
		/**
		 * Default constructor.
		 */
		public function FountController() {
			super();
		}
		
		/**
		 * @inheritDoc
		 */
		public function set appContext(appContext:IConfigurableApplicationContext):void {
			_appContext = appContext;
		}
		
		/**
		 * @inheritDoc
		 */
		public function registerCommandByObjectId(noteName:String, objectId:String):void {
			Assert.notNull(noteName, 'The notification name cannot be null.');
			Assert.notNull(objectId, 'The object id cannot be null.');
			Assert.isTrue(_appContext.containsObject(objectId), StringUtil.substitute('Application context does not contain an object with id: {0}', objectId));
			
			// if a command has already been registered the traditional puremvc
			// way, we need to remove it first
			if(commandMap[noteName]) {
				removeCommand(noteName);
			}
			
			// register with the view
			view.registerObserver(noteName, new Observer(executeCommand, this));
			commandMapIoc[noteName] = objectId;
		}
		
		/**
		 * @inheritDoc
		 */
		public function rc(noteName:String, command:*):void {
			Assert.notNull(_registrationClient, 'The registrationClient cannot be null.');
			var request:RegistrationRequestContext = new RegistrationRequestContext();
			request.noteName = noteName;
			request.command = command;
			request.controller = this;
			_registrationClient.handleRequest(request);
		}
		
		// ------ Protected members ------
		
		/** The command map for the object ids. */
		protected var commandMapIoc:Array;
		
		/** The application context. */
		protected var _appContext:IConfigurableApplicationContext;
		
		/** The registration client. */
		protected var _registrationClient:RegistrationClient;
		
		/**
		 * @inheritDoc
		 */
		override protected function initializeController() : void {
			super.initializeController();
			commandMapIoc = new Array();
			__internalAppContext = new XMLApplicationContext();
			__internalAppContext.addEmbeddedConfig(__configSource);
			__internalAppContext.load();
			_registrationClient = __internalAppContext.getObject('registrationClient') as RegistrationClient;
		}
		
		// ------ Private members ------
		
		[Embed(source="/app-context.xml",mimeType ="application/octet-stream")]
		private var __configSource:Class;
		
		private var __internalAppContext:XMLApplicationContext;
	}
}